package com.example.arraylist;

import java.util.EmptyStackException;

public class CircularArrayQueue<T> implements  Queue<T> {
    private final int DefaultCapacity=100;
    private int front,rear,count;
    public T[] queue;
    private int length;

    public CircularArrayQueue() {
        front=rear=count=0;
        queue=(T[])(new Object[DefaultCapacity]);
    }

    public CircularArrayQueue(int length){
        this.length=length;
        front=rear=count=0;
        queue=(T[])(new Object[length]);
    }

    @Override
    public void enqueue(T element) {
        queue[rear]=element;
        count++;
        if (size()==queue.length){
            System.out.println("Queue is full!Expand.");
            expandCapacity();
        }

        rear=(rear+1)%queue.length;

    }

    @Override
    public T dequeue() {
        if (isEmpty()){
            throw new EmptyStackException();
        }

        T result=queue[front];
        queue[front]=null;
        front=(front+1)%queue.length;
        count--;
        return result;
    }

    @Override
    public T first() {
        if (isEmpty()){
            throw new EmptyStackException();
        }
        return queue[front];
    }

    public int length(){
        return this.queue.length;
    }

    @Override
    public boolean isEmpty() {
        return count==0;
    }

    @Override
    public int size() {
        return count;
    }

    public void expandCapacity(){
        T[] larger=(T[])(new Object[queue.length*2]);
        length=length*2;

        for (int i=0;i<count;i++){
            larger[i]=queue[i];
        }
        front=0;
        rear=count;
        queue=larger;
    }

    @Override
    public String toString() {
        String output="";
        for (int i=0;i<queue.length;i++){
            if (queue[i]!=null){
                output=output+queue[i]+" ";
            }
        }
        return output;
    }

    public void change(int locate,T element){
        queue[locate]=element;
    }

    public T get(int locate){
        return queue[locate];
    }
}
